import { Cartesian3, Cartesian4, Color, PostProcessStage } from 'cesium';
import { isNil } from 'lodash';
import { useEffect } from 'react';
import { useCesium } from 'resium';
import { useAppSelector } from '../../../../store';
import { CesiumMath } from '../../../../utils/Type';

// 大雾
const FS_Fog = `float getDistance(sampler2D depthTexture, vec2 texCoords)
  {
      float depth = czm_unpackDepth(texture(depthTexture, texCoords));
      if (depth == 0.0) {
          return czm_infinity;
      }
      vec4 eyeCoordinate = czm_windowToEyeCoordinates(gl_FragCoord.xy, depth);
      return -eyeCoordinate.z / eyeCoordinate.w;
  }
  //根据距离，在中间进行插值
  float interpolateByDistance(vec4 nearFarScalar, float distance)
  {
      //根据常识，雾应该是距离远，越看不清，近距离内的物体可以看清
      //因此近距离alpha=0，远距离的alpha=1.0
      //本例中设置可见度为200米
      //雾特效的起始距离
      float startDistance = nearFarScalar.x;
      //雾特效的起始alpha值
      float startValue = nearFarScalar.y;
      //雾特效的结束距离
      float endDistance = nearFarScalar.z;
      //雾特效的结束alpha值
      float endValue = nearFarScalar.w;
      //根据每段距离占总长度的占比，插值alpha，距离越远，alpha值越大。插值范围0,1。
      float t = clamp((distance - startDistance) / (endDistance - startDistance), 0.0, 1.0);
      return mix(startValue, endValue, t);
  }
  vec4 alphaBlend(vec4 sourceColor, vec4 destinationColor)
  {
      return sourceColor * vec4(sourceColor.aaa, 1.0) + destinationColor * (1.0 - sourceColor.a);
  }
  uniform sampler2D colorTexture;
  uniform sampler2D depthTexture;
  uniform vec4 fogByDistance;
  uniform vec4 fogColor;
  in vec2 v_textureCoordinates;
  void main(void)
  {
      //获取地物距相机的距离
      float distance = getDistance(depthTexture, v_textureCoordinates);
      //获取场景原本的纹理颜色
      vec4 sceneColor = texture(colorTexture, v_textureCoordinates);
      //根据距离，对alpha进行插值
      float blendAmount = interpolateByDistance(fogByDistance, distance);
      //将alpha变化值代入雾的原始颜色中，并将雾与场景原始纹理进行融合
      vec4 finalFogColor = vec4(fogColor.rgb, fogColor.a * blendAmount);
      out_FragColor = alphaBlend(finalFogColor, sceneColor);
  }`;

export default function Demo() {
    const { viewer } = useCesium();
    const pos = useAppSelector((state) => state.scene.initPosition);

    useEffect(() => {
        if (isNil(viewer)) return;

        let lastStage: PostProcessStage | null = null;

        const removeStage = () => {
            lastStage && viewer.scene.postProcessStages.remove(lastStage), (lastStage = null);
        };

        const handleBigFog = () => {
            removeStage();
            const fog = new PostProcessStage({
                name: 'hi_fog',
                fragmentShader: FS_Fog,
                uniforms: {
                    fogByDistance: new Cartesian4(500, 0.0, 4000, 0.3), // 设置透明度
                    fogColor: Color.WHITE, // 设置颜色
                },
            });
            viewer.scene.postProcessStages.add(fog);
            lastStage = fog;
        };

        handleBigFog();

        const target = Cartesian3.fromDegrees(pos.longitude, pos.latitude, 1000);
        viewer.camera.setView({
            destination: target,
            orientation: {
                heading: viewer.camera.heading,
                pitch: CesiumMath.toDegrees(0),
                roll: viewer.camera.roll,
                up: Cartesian3.clone(Cartesian3.UNIT_Y),
            },
        });

        return () => {
            removeStage();
        };
    }, [pos, viewer]);
    return null;
}
